package com.linjiahao.servicebase.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.linjiahao.servicebase.common.BaseConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * @ClassName JWTUtil
 * @Description: jwt工具类
 * @Author linjiahao
 * @Date 23/12/2021
 **/
@Slf4j
public class JWTUtil {

    private static final String COSNT_JWT_SECRET = "linjiahao_~!@#$%^&*()_+";

    // ****************** 时间/秒 ************************//
    public static final long COSNT_one_minute = 60;
    public static final long CONST_half_hour = COSNT_one_minute * 30;
    public static final long CONST_one_hour = CONST_half_hour * 2;
    public static final long CONST_one_day = CONST_one_hour * 24;
    public static final long CONST_one_week = CONST_one_day * 7;
    public static final long CONST_half_month = CONST_one_week * 2;

    // 校验 token是否正确
    public static boolean verify(String token) {
        try {
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(COSNT_JWT_SECRET)).build();
            verifier.verify(token);
            return true;
        } catch (TokenExpiredException e) {
            log.error("token已经过期 {}", e.getMessage());
            return false;
        } catch (JWTVerificationException e) {
            log.error("token无效 {}", e.getMessage());
            return false;
        }
    }


    // 从 token中获取用户的userId
    public static Long getUserId(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("userId").asLong();
        } catch (JWTDecodeException e) {
            log.error("error：{}", e.getMessage());
            return null;
        }
    }

    /**
     * 从请求头获取userId
     * @param request
     * @return userId
     */
    public static Long getUserId(HttpServletRequest request) {
        try {
            String token = request.getHeader(BaseConstant.HEADER_TOKEN_KEY);
            if(StringUtils.isEmpty(token)){
                return null;
            }
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("userId").asLong();
        } catch (JWTDecodeException e) {
            log.error("error：{}", e.getMessage());
            return null;
        }
    }

    /**
     * 生成过期时间
     * @param ttl 多少秒后过期
     * @return 过期时间的时间戳，ms
     */
    public static long generateExpireTime(long ttl) {
        return System.currentTimeMillis() + ttl * 1000;
    }

    // 生成 token
    public static String generateTokenWithUserId(Long userId) {
        try {
            return JWT.create()
                    .withClaim("userId", userId)
                    .withExpiresAt(new Date(generateExpireTime(CONST_half_hour)))
                    .sign(Algorithm.HMAC256(COSNT_JWT_SECRET));
        } catch (Exception e) {
            log.error("error：{}", e.getMessage());
            return null;
        }
    }


}
